/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {defineComponent, onMounted, ref} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import {useThemeStore} from '@/store/theme/theme'
import {useMessage} from 'naive-ui'
import {useI18n} from 'vue-i18n'
import Dag from '../../components/dag'
import {
    queryProcessDefinitionByCode,
    updateProcessDefinition
} from '@/service/modules/process-definition'
import {
    WorkflowDefinition,
    SaveForm,
    TaskDefinition,
    Connect,
    Location
} from '../../components/dag/types'
import Styles from './index.module.scss'
import {useGraphAutoLayout} from '../../components/dag/use-graph-auto-layout'

interface SaveData {
    saveForm: SaveForm
    taskDefinitions: TaskDefinition[]
    connects: Connect[]
    locations: Location[]
}

export default defineComponent({
    name: 'WorkflowDefinitionDetails',
    setup() {
        const theme = useThemeStore()
        const route = useRoute()
        const router = useRouter()
        const message = useMessage()
        const {t} = useI18n()
        const projectCode = Number(route.params.projectCode)
        const code = Number(route.params.code)

        const definition = ref<WorkflowDefinition>()
        const readonly = ref(false)
        const isLoading = ref(true)
        const dagRef = ref()

        const refresh = () => {
            isLoading.value = true
            queryProcessDefinitionByCode(code, projectCode).then((res: any) => {
                readonly.value = res.processDefinition.releaseState === 'ONLINE'
                definition.value = res
                isLoading.value = false
                if (!res.processDefinition.locations) {
                    setTimeout(() => {
                        const graph = dagRef.value
                        const {submit} = useGraphAutoLayout({graph})
                        submit()
                    }, 1000)
                }
            })
        }

        const save = ({
                          taskDefinitions,
                          saveForm,
                          connects,
                          locations
                      }: SaveData) => {
            const globalParams = saveForm.globalParams.map((p) => {
                return {
                    prop: p.key,
                    value: p.value,
                    direct: 'IN',
                    type: 'VARCHAR'
                }
            })

            updateProcessDefinition(
                {
                    taskDefinitionJson: JSON.stringify(taskDefinitions),
                    taskRelationJson: JSON.stringify(connects),
                    locations: JSON.stringify(locations),
                    name: saveForm.name,
                    tenantCode: saveForm.tenantCode,
                    executionType: saveForm.executionType,
                    description: saveForm.description,
                    globalParams: JSON.stringify(globalParams),
                    timeout: saveForm.timeoutFlag ? saveForm.timeout : 0,
                    releaseState: saveForm.release ? 'ONLINE' : 'OFFLINE'
                },
                code,
                projectCode
            ).then((ignored: any) => {
                message.success(t('project.dag.success'))
                router.push({path: `/projects/${projectCode}/workflow-definition`})
            })
        }

        onMounted(() => {
            if (!code || !projectCode) return
            refresh()
        })

        return () => (
            <div
                class={[
                    Styles.container,
                    theme.darkTheme ? Styles['dark'] : Styles['light']
                ]}
            >
                {!isLoading.value && (
                    <Dag
                        ref={dagRef}
                        definition={definition.value}
                        onRefresh={refresh}
                        projectCode={projectCode}
                        onSave={save}
                        readonly={readonly.value}
                    />
                )}
            </div>
        )
    }
})
